import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';
import 'package:path_provider/path_provider.dart';

import '../ext/list_ext.dart';

class Log {
  static Logger? _logger;

  static Future<String> cacheDir() async {
    final cacheDir = Platform.isAndroid ? (await getExternalCacheDirectories())?.getOrNull(0) ?? await getTemporaryDirectory() : await getTemporaryDirectory();
    return '${cacheDir.path}/logs';
  }

  static Future<void> init() async {
    final dir = await cacheDir();
    final now = DateTime.now();

    String numToString(int num) => num.toString().padLeft(2, '0');
    final fileName = '${numToString(now.month)}_${numToString(now.day)}_${numToString(now.hour)}.txt';
    final file = File('$dir/$fileName');
    if (!file.existsSync()) {
      file.createSync(recursive: true);
    }

    _logger = Logger(
      filter: ReleaseFilter(),
      printer: PrettyPrinter(
          stackTraceBeginIndex: 5,
          methodCount: 0,
          excludeBox: {
            Level.verbose: true,
            Level.debug: false,
            Level.info: false,
            Level.warning: false,
            Level.error: false,
            Level.wtf: false,
          },
          colors: false,
          printTime: true),
      output: MultiOutput([
        ConsoleOutput(),
        FileOutput(file: file),
      ]),
    );

    _deleteExpiredLogs(dir);
  }

  static void _deleteExpiredLogs(String dir) async {
    final now = DateTime.now();

    DateTime parseLogDate(String name) {
      final dateArray = name.split('_');
      return DateTime(
        now.year,
        int.tryParse(dateArray[0]) ?? now.month,
        int.tryParse(dateArray[1]) ?? now.day,
      );
    }

    final logDirectory = Directory(dir);

    if (logDirectory.existsSync()) {
      final logs = logDirectory.listSync();
      for (var log in logs) {
        String name = log.path.split('/').last.replaceAll('.txt', '');
        final logData = parseLogDate(name);
        if (now.difference(logData).inDays > 7) {
          //超过7天的日志要删除
          log.deleteSync();
        }
      }
    }
  }

  static void v(dynamic message) {
    _logger?.v(message);
  }

  static void d(dynamic message) {
    _logger?.d(message);
  }

  static void i(dynamic message) {
    _logger?.i(message);
  }

  static void w(dynamic message) {
    _logger?.w(message);
  }

  static void e(dynamic message, {StackTrace? stackTrace}) {
    _logger?.e(message, time: null, error: null, stackTrace: stackTrace);
  }

  static void wtf(dynamic message) {
    _logger?.wtf(message);
  }
}

class ReleaseFilter extends LogFilter {
  @override
  bool shouldLog(LogEvent event) {
    if (kReleaseMode) {
      return event.level.index >= Level.warning.index;
    } else {
      return true;
    }
  }
}
